package controller

import (
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
	"mytest/code"
	"mytest/database"
	"mytest/flower-order/model"
	"mytest/util"
	"strings"
	"time"
)

type OrderController struct {
}

func (t *OrderController) Index(c *gin.Context) {
	var orderList []*model.Order
	var formHelper util.FormHelper
	params := [][]string{
		{"list", "string"},
		{"page", "int", "num|has"},
		{"limit", "int", "num|has"},
		{"searchParams", "string-no-filter"},
	}

	paramMap, err := formHelper.Params(params, c)
	if err != nil {
		c.JSON(code.Success, util.ReturnError(code.ParamErr, err.Error()))
		return
	}
	conditions := " 1=1 "
	//0.未处理 1.待配送 2.已完成 3.退款
	switch paramMap["list"].(string) {
	case "undeal":
		conditions += " and `order_status` =  0 "
	case "send":
		conditions += " and `order_status` =  1 "
	case "complete":
		conditions += " and `order_status` =  2 "
	case "refund":
		conditions += " and `order_status` =  3 "
	}
	if len(paramMap["searchParams"].(string)) > 0 {
		searchParams := make(map[string]string)
		err = json.Unmarshal([]byte(paramMap["searchParams"].(string)), &searchParams)
		if err != nil {
			c.JSON(code.Success, util.ReturnError(code.ParamErr, err.Error()))
			return
		}
		for k, v := range searchParams {
			if v == "" {
				continue
			}
			switch k {
			case "vx":
				fallthrough
			case "name":
				fallthrough
			case "mobile":
				fallthrough
			case "address":
				conditions += fmt.Sprintf(" and `%s` like  '%%%s%%' ", k, v)
			case "send_time_area":
				sendTimeArea := strings.Split(v, " - ")
				conditions += fmt.Sprintf(" and `start_time` >=  '%s' and `end_time` <=  '%s' ", sendTimeArea[0], sendTimeArea[1])
			default:
				conditions += fmt.Sprintf(" and `%s` =  '%s' ", k, v)
			}
		}
	} else {
		conditions += fmt.Sprintf(" and `year` =  '%v' ", time.Now().Local().Year())
		conditions += fmt.Sprintf(" and `holiday_type` =  '%v' ", GetConfigByKey(HOLIDAY_TYPE))
	}

	limit := paramMap["limit"].(int)
	page := paramMap["page"].(int)
	offset := (page - 1) * limit
	var count int64
	database.DB.Debug().Model(model.Order{}).Select("id").Where(conditions).Count(&count)
	err = database.DB.Debug().Model(model.Order{}).
		Select("*,datetime(created_at) as created_at,datetime(updated_at) as updated_at,datetime(deleted_at) as deleted_at,datetime(start_time) as start_time,datetime(end_time) as end_time").
		Preload("Img").
		Where(conditions).
		Limit(limit).Offset(offset).
		Order("send_time asc").
		Find(&orderList).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		c.JSON(code.Success, util.ReturnError(code.SysErr, err.Error()))
		return
	}
	response := util.ReturnSuccess(orderList)
	response["count"] = count
	c.JSON(code.Success, response)
	return
}

func (t *OrderController) Show(c *gin.Context) {
	var order model.Order
	var formHelper util.FormHelper
	params := [][]string{
		{"id", "string", "required|num"},
	}
	paramMap, err := formHelper.Params(params, c)
	if err != nil {
		c.JSON(code.Success, err.Error())
		return
	}
	err = database.DB.Debug().Model(model.Order{}).
		Select("*,datetime(start_time) as start_time,datetime(end_time) as end_time").
		Preload("Img").
		Where("id = ?", paramMap["id"]).
		First(&order).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		c.JSON(code.Success, util.ReturnError(code.SysErr, err.Error()))
		return
	}
	c.JSON(code.Success, util.ReturnSuccess(order))
	return
}

func (t *OrderController) Add(c *gin.Context) {
	var order model.Order
	err := c.BindJSON(&order)
	if err != nil {
		c.JSON(code.Success, util.ReturnError(code.ParamErr, err.Error()))
		return
	}
	if order.StartTime == "" {
		order.StartTime = order.SendTime + " 00:00"
	}
	if order.EndTime == "" {
		order.EndTime = order.SendTime + " 23:59"
	}
	nowTimeStr := time.Now().Local().Format(util.TimeLayout)
	order.CreatedAt = nowTimeStr
	order.UpdatedAt = nowTimeStr
	order.Year = time.Now().Local().Year()
	err = database.DB.Debug().Model(model.Order{}).Create(&order).Error
	if err != nil {
		c.JSON(code.Success, util.ReturnError(code.SysErr, err.Error()))
		return
	}
	c.JSON(code.Success, util.ReturnSuccess(nil))
	return
}

func (t *OrderController) Edit(c *gin.Context) {
	var dataMap map[string]interface{}
	err := c.BindJSON(&dataMap)
	if err != nil {
		c.JSON(code.Success, util.ReturnError(code.ParamErr, err.Error()))
		return
	}
	dataMap["updated_at"] = time.Now().Local().Format(util.TimeLayout)
	if _, ok := dataMap["end_time"]; ok {
		if dataMap["end_time"] == "" {
			dataMap["end_time"] = dataMap["start_time"]
		}
	}
	if _, ok := dataMap["deal_time"]; ok {
		dataMap["deal_time"] = dataMap["updated_at"]
		dataMap["order_status"] = 1 //0.未处理 1.待配送 2.已完成 3.退款
	}
	if _, ok := dataMap["complete_time"]; ok {
		dataMap["complete_time"] = dataMap["updated_at"]
		dataMap["order_status"] = 2 //0.未处理 1.待配送 2.已完成 3.退款
	}
	if _, ok := dataMap["refund_time"]; ok {
		dataMap["refund_time"] = dataMap["updated_at"]
		dataMap["order_status"] = 3 //0.未处理 1.待配送 2.已完成 3.退款
	}

	id := int(dataMap["id"].(float64))
	delete(dataMap, "id")
	delete(dataMap, "deleted_at")
	delete(dataMap, "created_at")
	delete(dataMap, "img")
	delete(dataMap, "category")
	err = database.DB.Debug().Model(&model.Order{Id: id}).Updates(dataMap).Error
	if err != nil {
		c.JSON(code.Success, util.ReturnError(code.SysErr, err.Error()))
		return
	}
	c.JSON(code.Success, util.ReturnSuccess(dataMap))
	return
}
